const Model = require('../dbs/model/getCollection.js')
const LocationFenceSchema = require('../dbs/schema/locationFenceSchema.js')
const TriggerFenceRecordSchema = require('../dbs/schema/triggerFenceRecordSchema.js')
const result = require("../com/result.js")
const log = require("../com/logConfig.js")

/**
 * 存电子围栏
 * @param {*} ctx 
 * @param {*} next 
 */
let saveFence = async (ctx, next) => {

    let param = ctx.request.body;
    if ((!param.coordinates && !param.cirCoordinate)
        || (param.coordinates && param.cirCoordinate)
        || (!param.schoolId && !param.parentId)
        || (param.schoolId && param.parentId)
    ) {
        ctx.body = result.go(result.code.CODE_501);
        return;
    }
    if (param.parentId) {
        if (!param.studentId || !param.cirCoordinate || param.coordinates) {
            ctx.body = result.go(result.code.CODE_501);
            return;
        }
    }
    if (param.studentId) {
        if (param.schoolId || !param.parentId || !param.cirCoordinate || param.coordinates) {
            ctx.body = result.go(result.code.CODE_501);
            return;
        }
    }

    if (param.coordinates) {
        param.coordinate = {
            type: 'Polygon',
            coordinates: [JSON.parse(param.coordinates)]
        };
        delete param.coordinates;
    } else {
        if (param.cirCoordinate.r <= 0 || !param.cirCoordinate.latitude || !param.cirCoordinate.longitude) {
            ctx.body = result.go(result.code.CODE_501);
            return;
        }
    }

    let LocationFenceModel = await Model.getComModel({
        dataBase: 'com_info',
        tableName: 'location_fence',
        schema: LocationFenceSchema
    });
    if (param.schoolFence) {
        if (!param.schoolId) {
            ctx.body = result.go(result.code.CODE_501);
            return;
        }
        let isEx = new Promise((r, j) => {
            LocationFenceModel.findOne({
                schoolId: param.schoolId,
                schoolFence: true
            }).exec((error, doc) => {
                if (doc) {
                    return r(true);
                }
                return r(false);
            });
        });
        if (await isEx) {
            ctx.body = result.go(result.code.CODE_504, "一个学校只能有一个电子围栏");
            return;
        }
    }

    let property = {};
    //进入圈内报警
    if (param.inAlarm === true || param.inAlarm === 'true') {
        delete param.inAlarm;
        property.in = {
            //设置的进入此电子围栏多少次会报警
            proCount: 1,
            //目前已经进入多少次了，默认是0次
            triggerCount: 0
        };
    }
    //离开圈内报警
    if (param.outAlarm === true || param.outAlarm === 'true') {
        delete param.outAlarm;
        property.out = {
            //设置的进入此电子围栏多少次会报警
            proCount: 1,
            //目前已经进入多少次了，默认是0次
            triggerCount: 0
        };
    }

    if (property.in || property.out) {
        param.property = property;
    }

    // 存电子围栏
    new LocationFenceModel(param).save();

    ctx.body = result.go(result.code.CODE_200);

    return;
};

/**
 * 查询电子围栏
 * @param {*} ctx 
 * @param {*} next 
 */
let getFence = async (ctx, next) => {
    let param = ctx.query;
    let headerUser = JSON.parse(ctx.headers['authorization-user']);
    let schoolId = headerUser.orgId;


    if (!(schoolId && param.isSchool) && !param.parentId && !param.fenceId && !param.studentId) {
        ctx.body = result.go(result.code.CODE_501);
        return;
    }

    let LocationFenceModel = await Model.getComModel({
        dataBase: 'com_info',
        tableName: 'location_fence',
        schema: LocationFenceSchema
    });

    //查电子围栏
    return await new Promise((r, j) => {
        let filter = {};
        if (param.fenceId) {
            filter._id = param.fenceId;
        } else if (param.parentId) {
            filter.parentId = param.parentId;
        } else if (schoolId && param.isSchool) {
            filter.schoolId = schoolId;
            if (param.schoolFence) {
                filter.schoolFence = true;
            }
        }
        if (param.studentId) {
            filter.studentId = param.studentId;
        }
        if (param.useFence == true || param.useFence == 'true') {
            filter.useFence = true;
        }
        if (param.useFence == false || param.useFence == 'false') {
            filter.useFence = false;
        }
        LocationFenceModel
            .find(filter)
            .sort({ time: -1 })
            .exec((error2, doc) => {
                ctx.body = result.go(result.code.CODE_200, doc);
                return r();
            });
    });
};

/**
 * 修改某个电子围栏
 * @param {*} json 
 */
let updateFence = async (ctx, next) => {
    let fenceId = ctx.request.body.fenceId;
    let remark = ctx.request.body.remark;
    let useFen = ctx.request.body.useFence;
    let coordinates = ctx.request.body.coordinates;
    let cirCoordinate = ctx.request.body.cirCoordinate;
    let inAlarm = ctx.request.body.inAlarm;
    let outAlarm = ctx.request.body.outAlarm;
    if (!fenceId
        || (coordinates && cirCoordinate)
    ) {
        ctx.body = result.go(result.code.CODE_501);
        return;
    }

    //组装新数据
    let newData = {
        updateTime: String(Date.now())
    };
    let where = {
        '_id': fenceId
    };
    if (coordinates) {
        newData.coordinate = {
            "type": "Polygon",
            "coordinates": [JSON.parse(coordinates)]
        }
        where.coordinate = { $exists: true };
    } else if (cirCoordinate) {
        if (cirCoordinate.r <= 0 || !cirCoordinate.latitude || !cirCoordinate.longitude) {
            ctx.body = result.go(result.code.CODE_501);
            return;
        }
        newData.cirCoordinate = cirCoordinate;
        where.cirCoordinate = { $exists: true };
    }
    if (remark) {
        newData.remark = remark;
    }
    if (useFen == true || useFen == 'true') {
        newData.useFence = true;
    }
    if (useFen == false || useFen == 'false') {
        newData.useFence = false;
    }
    let property = {};
    //进入圈内报警
    if (inAlarm === true || inAlarm === 'true') {
        property.in = {
            //设置的进入此电子围栏多少次会报警
            proCount: 1,
            //目前已经进入多少次了，默认是0次
            triggerCount: 0
        };
    }
    //离开圈内报警
    if (outAlarm === true || outAlarm === 'true') {
        property.out = {
            //设置的进入此电子围栏多少次会报警
            proCount: 1,
            //目前已经进入多少次了，默认是0次
            triggerCount: 0
        };
    }
    if (property.in || property.out) {
        newData.property = property;
    }

    let LocationFenceModel = await Model.getComModel({
        dataBase: 'com_info',
        tableName: 'location_fence',
        schema: LocationFenceSchema
    });
    return await new Promise((r, j) => {
        LocationFenceModel.updateOne(where, newData).exec((error2, doc) => {
            if (doc && doc.n == 1) {
                ctx.body = result.go(result.code.CODE_200);
            } else {
                ctx.body = result.go(result.code.CODE_503, null, '修改失败');
            }
            return r();
        });
    });
}

/**
 * 删除一个电子围栏
 * @param {*} ctx 
 * @param {*} next 
 */
let delFence = async (ctx, next) => {
    let fenceId = ctx.request.body.fenceId;
    let schoolId = ctx.request.body.schoolId;
    let parentId = ctx.request.body.parentId;
    if (!fenceId || (!schoolId && !parentId) || (schoolId && parentId)) {
        ctx.body = result.go(result.code.CODE_501);
        return;
    }

    let LocationFenceModel = await Model.getComModel({
        dataBase: 'com_info',
        tableName: 'location_fence',
        schema: LocationFenceSchema
    });

    let where = {
        '_id': fenceId
    };
    if (schoolId) {
        where.schoolId = schoolId;
    } else if (parentId) {
        where.parentId = parentId;
    }

    return await new Promise((r, j) => {
        LocationFenceModel
            .deleteOne(where)
            .exec((error2, doc) => {
                if (doc) {
                    ctx.body = result.go(result.code.CODE_200);
                } else {
                    ctx.body = result.go(result.code.CODE_503, null, '删除失败');
                }
                return r();
            });
    });
}

/**
 * 判断一个点是否在某个学校范围内1
 * @param {*} json 
 */
let judgeSchoolFence = async (json) => {
    if (!json.schoolId || !json.coordinate) { return false; }
    let LocationFenceModel = await Model.getComModel({
        dataBase: 'com_info',
        tableName: 'location_fence',
        schema: LocationFenceSchema
    });
    return await new Promise((r, j) => {
        LocationFenceModel.find({
            schoolId: json.schoolId,
            schoolFence: true,
            coordinate:
            {
                $geoIntersects:
                {
                    $geometry: {
                        "type": "Point",
                        "coordinates": json.coordinate
                    }
                }
            }
        }).exec((error2, doc) => {
            if (doc[0] && (doc[0].coordinate.coordinates.length > 0)) {
                return r(true);
            } else {
                return r(false);
            }
        });
    })

}

/**
 * 查询触发电子围栏报警记录
 * @param {*} ctx 
 * @param {*} next 
 */
let getFenceAlarm = async (ctx, next) => {
    let param = ctx.query;
    let studentIds = param.studentIds;
    let fenceIds = param.fenceIds;

    if ((!studentIds && !fenceIds)
        || !param.pageNum
        || !param.size
    ) {
        ctx.body = result.go(result.code.CODE_501);
        return;
    }

    let pageNum = Number(param.pageNum) - 1;
    let size = Number(param.size);

    let TriggerFenceRecordModel = await Model.getComModel({
        dataBase: 'com_info',
        tableName: 'trigger_fence_record',
        schema: TriggerFenceRecordSchema
    });

    return await new Promise((r, j) => {
        let filter = {};
        if (studentIds) {
            filter.studentId = {
                $in: JSON.parse(studentIds)
            };
        }
        if (fenceIds) {
            filter.fenceId = {
                $in: JSON.parse(fenceIds)
            };
        }
        if (param.startTime) {
            //数据库的时间大于等于这个时间
            let i = String(param.startTime).length > 10 ? 1 : 1000;
            let timeNum = parseInt(param.startTime, 10) * i;
            filter.createTime = {
                $gte: new Date(timeNum)
            };
        }
        if (param.endTime) {
            //数据库的时间小于这个时间
            let i = String(param.endTime).length > 10 ? 1 : 1000;
            let timeNum = parseInt(param.endTime, 10) * i;
            let endTime = new Date(timeNum);
            if (filter.createTime && filter.createTime['$gte']) {
                filter.createTime['$lt'] = endTime;
            } else {
                filter.createTime = {
                    $lt: endTime
                };
            }
        }
        let i = 0;
        let data = {};
        TriggerFenceRecordModel.countDocuments(filter, (error, count) => {
            i++;
            data.allCount = count;
            if (i == 2) {
                ctx.body = result.go(result.code.CODE_200, data);
                return r();
            }
        });
        TriggerFenceRecordModel
            .find(filter)
            .skip(pageNum * size)
            .limit(size)
            .sort({ createTime: -1 })
            .exec((error2, doc) => {
                i++;
                data.data = doc;
                if (i == 2) {
                    ctx.body = result.go(result.code.CODE_200, data);
                    return r();
                }
            });
    });
};

/**
 * 测试判断一个点是否在某个区域范围内
 * @param {*} json 
 */
let test = async (ctx, next) => {
    let LocationFenceModel = await Model.getComModel({
        dataBase: 'com_info',
        tableName: 'location_fence',
        schema: LocationFenceSchema
    });
    await new Promise((r, j) => {
        LocationFenceModel.find({
            schoolId: '500107001',
            schoolFence: true,
            coordinate:
            {
                $geoIntersects:
                {
                    $geometry: {
                        "type": "Point",
                        "coordinates": [113.33831, 23.137335]
                    }
                }
            }
        }).exec((error2, doc) => {
            ctx.body = result.go(result.code.CODE_200, doc);
            return r();
        });
    })

}


module.exports = {
    saveFence,
    getFence,
    judgeSchoolFence,
    updateFence,
    delFence,
    getFenceAlarm,
    test
}  